#ifndef _ACCEPTOR_WIN_H_
#define _ACCEPTOR_WIN_H_


#include "acceptor.h"
#include <memory>


// #include <MSWSock.h>
// #include <minwinbase.h>
// #include <ws2def.h>
// #include <winsock2.h>
// #include <ws2tcpip.h>

#include "socket.h"
#include "poller.h"
#include <assert.h>

constexpr int IO_CONTEXT_COUNT = 64;
constexpr int IO_CONTEXT_BUF_SIZE = 1024;

struct global_init
{   
	global_init()
	{
		WSADATA data;
		WORD wVersion = MAKEWORD(2, 2);
		int err = WSAStartup(wVersion, &data);
		assert(err == 0);
	}

	~global_init()
	{
		WSACleanup();
	}
};


static global_init s;

struct IOContext
{
	OVERLAPPED overlapped{};
	WSABUF wsaBuf{ IO_CONTEXT_BUF_SIZE, buffer };
	CHAR buffer[IO_CONTEXT_BUF_SIZE]{};
	socket_fd socket = ERROR_SOCKET_FD;
	DWORD nBytes = 0;
	uint8_t ntype = 0;
	void reset()
	{
		clear();
		socket = ERROR_SOCKET_FD;
	}

	void clear()
	{
		ntype = 0;
		if (wsaBuf.buf != NULL)
			memset(wsaBuf.buf, 0, IO_CONTEXT_BUF_SIZE);
		memset(buffer, 0, IO_CONTEXT_BUF_SIZE);
		memset(&overlapped, 0, sizeof(overlapped));
	}

	bool post(socket_fd listen_fd, int af);
};

namespace as
{
namespace snet
{
class EventLoop;
class Acceptor::impl : public PollerInstance
{
public:
	impl(Acceptor *acc, std::shared_ptr<EventLoop> &ev);
	~impl();

	bool start(const EndPoint &ep);
	void stop();
	void update();

	virtual void on_poll(void *key, void *ev);
public:
	std::shared_ptr<EventLoop> &m_ev;
	std::shared_ptr<Poller> m_poller;

	class WaitingIo;
	WaitingIo *m_waitingIo;

	std::shared_ptr<BaseSocket> m_ac_socket;
	EndPoint m_ep;

	std::atomic_bool m_running = false;
};

}
}


#endif